package dcutli;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;


public class FileUtli {

    //获取主板名称
    public static String getBoardName(){
        return  getSystemProperty("ro.board.platform","unknown");
    }

    public static int dpToPx(Context context, int dps) {
        return Math.round(context.getResources().getDisplayMetrics().density * dps);
    }

    //https://www.cnblogs.com/yongdaimi/p/13214479.html
    //将指定的某一个比特位置0、置1、取反
    /**
     * Set the specified bit to 1
     *
     * @param originByte Raw byte value
     * @param bitIndex   bit index (From 0~7)
     * @return Final byte value
     */
    public static byte setSpecifiedBitTo1(byte originByte, int bitIndex) {
        return originByte |= (1 << bitIndex);
    }

    /**
     * Set the specified bit to 0
     *
     * @param originByte Raw byte value
     * @param bitIndex   bit index (From 0~7)
     * @return Final byte value
     */
    public static byte setSpecifiedBitTo0(byte originByte, int bitIndex) {
        return originByte &= ~(1 << bitIndex);
    }

    /**
     * Invert the specified bit
     *
     * @param originByte Raw byte value
     * @param bitIndex   bit index (From 0~7)
     * @return Final byte value
     */
    public static byte setSpecifiedBitToReverse(byte originByte, int bitIndex) {
        return originByte ^= (1 << bitIndex);
    }

    /**
     * Get the value of the specified bit
     *
     * @param originByte Raw byte value
     * @param bitIndex   bit index (From 0~7)
     * @return Final byte value
     */
    public static byte getSpecifiedBitValue(byte originByte, int bitIndex) {
        return (byte) ((originByte) >> (bitIndex) & 1);
    }

    public static void CreateIfNotExist(String path)
    {
        File file = new File(path);
        if (!file.exists()) {//如果文件夹不存在
            file.mkdir();//创建文件夹
        }
        file = null;
    }

    public static int random(int min, int max){
        if( min == max)
            return 0;

        int nRes = min + (int)(System.currentTimeMillis()%(max-min));

        return nRes;
    }

    public static boolean isEthNetworkOk(Context context) {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo mobNetInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET);
        if (mobNetInfo != null) {
            return mobNetInfo.isConnected();
        }
        return false;
    }

    public static boolean isWIFINetworkOk(Context context) {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo mobNetInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (mobNetInfo != null) {
            return mobNetInfo.isConnected();
        }
        return false;
    }

    public static boolean isMobileNetworkOk(Context context) {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mobNetInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (mobNetInfo != null) {
            return mobNetInfo.isConnected();
        }
        return false;
    }

    //来源https://www.sharezer.com/archives/1314
    public static String execRootCmd(String cmd) {
        String result = "";
        DataOutputStream dos = null;
        DataInputStream dis = null;

        try {
            Process p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令
            dos = new DataOutputStream(p.getOutputStream());
            dis = new DataInputStream(p.getInputStream());

            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            String line = null;

            BufferedReader br = new BufferedReader(new InputStreamReader(dis));
            while ((line = br.readLine()) != null) {
                result += line;
                result += "\n";
            }
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static boolean isExist(String string) {
        File mFile = new File(string);
        return mFile.exists();
    }

    public static String getIPv4(String device){
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                if (device.equals(intf.getDisplayName()) == false) { //判断网口是否在使用，判断是否时我们获取的网口
                    continue;
                }

                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        return  inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception e) {
             Log.e("getIPv4", "获取IP信息出错。");
        }

        return null;
    }

    private static String getSystemProperty(String property, String defaultValue) {
        try {
            Class clazz = Class.forName("android.os.SystemProperties");
            Method getter = clazz.getDeclaredMethod("get", String.class);
            String value = (String)getter.invoke(clazz.newInstance(), property);
            if (!TextUtils.isEmpty(value)) {
                return value;
            }
        } catch (Exception var6) {
            Log.e("FileUtli", "Unable to read system properties" + var6.toString());
        }

        return defaultValue;
    }

    public static void deleteFile(String path)
    {
        File file = new File(path);
        if (file.isFile() && file.exists()) {
            file.delete();
        }
        file = null;
    }

    //传入绝对路径
    public static String getFileNameWithoutSuffix(String path) {
        if(TextUtils.isEmpty(path)){
            return "";
        }
        int start = path.lastIndexOf("/");
        if (start != -1 ) {
            String fname = path.substring(start + 1);
            String prefix=fname.substring(fname.lastIndexOf("."));
            int num=prefix.length();//得到后缀名长度
            String fileOtherName=fname.substring(0, fname.length()-num);//得到文件名。去掉了后缀
            return fileOtherName;
        } else {
            return "";
        }
    }

    private static String getAppDataFilePath(Context context) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            //cachePath = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath();
            cachePath = context.getFilesDir().getAbsolutePath();
//            cachePath = context.getExternalCacheDir().getPath();//也可以这么写，只是返回的路径不一样，具体打log看
        } else {
            cachePath = context.getFilesDir().getAbsolutePath();
//            cachePath = context.getCacheDir().getPath();//也可以这么写，只是返回的路径不一样，具体打log看
        }
        return cachePath;
    }

    //从assets 文件夹中获取文件并读取数据
    public static String getFromAssets(Context context, String fileName){
        String result = "";
        try {
            InputStream in = context.getResources().getAssets().open(fileName);
//获取文件的字节数
            int lenght = in.available();
//创建byte数组
            byte[]  buffer = new byte[lenght];
//将文件中的数据读到byte数组中
            in.read(buffer);
            //result = EncodingUtils.getString(buffer, ENCODING);
            result= new String(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String fmtTime(long tm){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curDate = new Date(tm);
        String curTime = formatter.format(curDate);
        return curTime;
    }

    public static byte[] getFromAssetsBin(Context context, String fileName){
        try {
            InputStream in = context.getResources().getAssets().open(fileName);
//获取文件的字节数
            int lenght = in.available();
//创建byte数组
            byte[]  buffer = new byte[lenght];
//将文件中的数据读到byte数组中
            in.read(buffer);
            //result = EncodingUtils.getString(buffer, ENCODING);
            return buffer;//= new String(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //获取默认桌面 //https://blog.csdn.net/Programming2012/article/details/41983043
    //用于获取的默认桌面，部分机型可能返回结果只有“android” 本问题在7.1上第一次启动稳定重现
    public static String getHomeLauncher(Context context)
    {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
        String currentHomePackage = resolveInfo.activityInfo.packageName;
        return currentHomePackage;
    }

    public static String getAppName(Context context, String packageName){
        String str = packageName;
        PackageInfo info = null;
        PackageManager pm = context.getPackageManager();
        try {
            info = pm.getPackageInfo(str,PackageManager.GET_ACTIVITIES);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }

        if( info == null)
            return  null;
        else
            return info.applicationInfo.loadLabel(pm).toString();
    }



    /**
     * 检查指定的服务是否正在运行
     * @param mcontext
     * @param serviceName   "当前包名."+"服务name"
     * @return
     */
    public static boolean serviceIsRun(Context mcontext, String serviceName){
        boolean serviceIsRun =false;
        ActivityManager activityManager = (ActivityManager) mcontext
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> runningServices = activityManager.getRunningServices(100);
        for (int i = 0; i < runningServices.size(); i++) {
            String s = runningServices.get(i).service.getClassName();
            if (s.equals(serviceName)) {
                serviceIsRun =true;
            }
        }
        return serviceIsRun;
    }

    //检查包是否存在
    public static boolean isAppExist(Context context, String packname) {
        PackageInfo packageInfo = null;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(packname, 0);
        } catch (PackageManager.NameNotFoundException e) {
            //e.printStackTrace();
            return false;
        }
        return packageInfo != null;
    }


    public static boolean isAppInstalled(Context context, String packageName){
        PackageManager manager = context.getPackageManager();
        List<PackageInfo> pkgList = manager.getInstalledPackages(0);
        for (int i = 0; i < pkgList.size(); i++) {
            PackageInfo pI = pkgList.get(i);
            if (pI.packageName.equalsIgnoreCase(packageName ))
                return true;
        }
        return false;
    }

    public static StringBuffer readFileByBytes(String fileName) {
        File file = new File(fileName);
        StringBuffer sb = new StringBuffer();

        if (file.isFile() && file.exists()) { //判断文件是否存在

            byte[] tempbytes = new byte[1024];
            int byteread = 0;
            try {
                InputStream in = new FileInputStream(file);
                //ReadFromFile1.showAvailableBytes(in);
                // 读入多个字节到字节数组中，byteread为一次读入的字节数
                while ((byteread = in.read(tempbytes)) != -1) {
                    //  System.out.write(tempbytes, 0, byteread);
                    String str = new String(tempbytes, 0, byteread);
                    sb.append(str);
                }
            } catch (FileNotFoundException e) {
                //read file failed.
                return sb;
            } catch (IOException dd) {

            }

        } else {
            return sb;
        }

        return sb;
    }

    /**
     * 32位MD5加密
     * @param content -- 待加密内容
     * @return
     */
    public static String md5Decode32(String content) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException",e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UnsupportedEncodingException", e);
        }
        //对生成的16字节数组进行补零操作
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10){
                hex.append("0");
            }
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }

    //根据摄像头测距-返回单位毫米-工作条件1080P摄像头 //参数2：摄像头分辨率参考值1920.因为调的时候是用这个分辨率调的。其他分辨率不保证准确，请自行调整
    /*public static int WidthToDistance(int faceW, int resolutionW){
        float distance = 0.0f;
        if( faceW >=700 )
        {
            distance = 0.3f - (faceW-700.0f)/1000.0f;
        }else if( faceW <700 && faceW >= 500){
            distance = 0.3f - (faceW - 700.0f)/1000.0f;
        }else if(faceW < 500 && faceW>= 200){
            //200 = 1m //500 = 0.5
            distance = 0.5f -(faceW-500.0f)/600.0f;
        }
        else if(faceW <200 && faceW>= 150){
            distance = 1.0f - (faceW-200.0f)/100.0f;
        }else if(faceW<150){
            distance = 1.5f - (faceW - 150.0f)/50.0f;
        }

        return  (int)(distance*1000/1920*resolutionW);
    }*/

    //根据距离补偿温度的函数
    /*
    public static float DistanceTempBuchang(int dis_in_mm ){
        float distance = 0.0f;

        if(dis_in_mm>=900){
            distance = 0.5f + (dis_in_mm-700.0f)/500.0f;
        }
        else if( dis_in_mm <900 && dis_in_mm >= 800 )
        {
            distance = 0.4f + (dis_in_mm-700.0f)/500.0f;
        }
        else if( dis_in_mm <800 && dis_in_mm >= 700 )
        {
            distance = 0.3f + (dis_in_mm-600.0f)/400.0f;
        }else if(dis_in_mm <700 && dis_in_mm >= 600){
            distance = 0.2f + (dis_in_mm-600.0f)/300.0f;
        }
        else if( dis_in_mm <600 && dis_in_mm >= 500){
            distance = 0.1f + (dis_in_mm-500.0f)/400.0f;
        }else if(dis_in_mm < 500 && dis_in_mm>= 400){
            //200 = 1m //500 = 0.5
            distance = -0.2f +(dis_in_mm-500.0f)/300.0f;
        }
        else if(dis_in_mm <400 && dis_in_mm>= 300){
            distance = -0.4f + (dis_in_mm-400.0f)/100.0f;
        }else if(dis_in_mm<300 && dis_in_mm>= 200){
            distance = -0.5f +(dis_in_mm - 300.0f)/100.0f;
        }else if(dis_in_mm<200 && dis_in_mm>= 100){
            distance = -0.7f +(dis_in_mm - 200.0f)/100.0f;
        }

        return (distance);
    }*/

    public static Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) {
        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        try {
            Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
            return bm1;
        } catch (OutOfMemoryError ex) {
        }
        return null;
    }

    public static String bytes2HexString(byte[] b, int len) {
        String ret = "";
        for (int i = 0; i < len; i++) {
            String hex = Integer.toHexString(b[ i ] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }

    public static String getUsbStoragePath() {
        String usbPath = null;
        String usbBasePath = "/mnt/usb_storage/";
        String ApkPath = null;
        File file = new File(usbBasePath);

        try {
            if (file.exists() && file.isDirectory()) {
                File[] files = file.listFiles();
                if (files.length > 0) {
                    usbPath = files[0].getAbsolutePath();
                   // this.LOGD("steve : get file path " + usbPath);
                    if (usbPath.contains("USB_DISK")) {
                      //  this.LOGD("steve : open " + usbPath);
                        File usbFile = new File(usbPath);
                        if (usbFile.exists() && usbFile.isDirectory()) {
                            File[] usbFiles = usbFile.listFiles();
                            if (usbFiles.length > 0) {
                                usbPath = usbFiles[0].getAbsolutePath();
                                //this.LOGD("steve : usbPath " + usbPath);
                            }
                        }
                    }
                }
            }
        } catch (Exception var9) {
            var9.printStackTrace();
        }

        return usbPath;
    }

    public static Bitmap bitmapZoomByScale(Bitmap srcBitmap, float scaleWidth, float scaleHeight) {
        int width = srcBitmap.getWidth();
        int height = srcBitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, width, height, matrix, true);
        if(bitmap != null) {
            return bitmap;
        }else {
            return srcBitmap;
        }
    }

    public static String ReadFileB64(String filePath){
        File file = new File(filePath);
        if (file.isFile() && file.exists()) { //判断文件是否存在

            StringBuffer sb = new StringBuffer();
            byte[] tempbytes = new byte[1024];
            int byteread = 0;
            try {
                InputStream in = new FileInputStream(file);
                //ReadFromFile1.showAvailableBytes(in);
                // 读入多个字节到字节数组中，byteread为一次读入的字节数
                while ((byteread = in.read(tempbytes)) != -1) {
                    //  System.out.write(tempbytes, 0, byteread);
                    String str = new String(tempbytes, 0, byteread);
                    sb.append(str);
                }
            } catch (FileNotFoundException e) {
                //read file failed.
                return  null;
            } catch (IOException dd) {
                return  null;
            }

            String jsonString = new String(sb);
            jsonString =new String(Base64.decode(jsonString,Base64.DEFAULT));
            return jsonString;
        }

        return  null;
    }

    public static void simpleWriteFile(String path, byte []data){
        try {
            FileOutputStream fos = null;
            fos = new FileOutputStream(new File(path));
            fos.write(data, 0, data.length);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
    }

    public static byte[] simpleReadFile(String path){
        File f= new File(path );
        FileInputStream fileInputStream = null;
        byte[] buffer =null;
        try {
            fileInputStream = new FileInputStream(f);
            buffer = new byte[(int)f.length()];
            int len = fileInputStream.read(buffer);
            // 关闭输入流
            fileInputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return buffer;
    }

    public static  void WriteFileB64(String filePath, String fileContent){

        String encodedString = Base64.encodeToString(fileContent.getBytes(), Base64.DEFAULT);

        FileOutputStream outSTr = null;
        try {
            outSTr = new FileOutputStream(new File(filePath));
            BufferedOutputStream Buff  = new BufferedOutputStream(outSTr);
            Buff.write(encodedString.getBytes());
            Buff.flush();
            Buff.close();
            outSTr.close();
            outSTr = null;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String byteToStr(byte[] buffer) {
        try {
            int length = 0;
            for (int i = 0; i < buffer.length; ++i) {
                if (buffer[i] == 0) {
                    length = i;
                    break;
                }
            }
            return new String(buffer, 0, length, "UTF-8");
        } catch (Exception e) {
            return "";
        }
    }


    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

        }
        return d;
    }

    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 方法1，使用for循环
     * @param list
     * 将被转换为byte[]的List<Byte>
     * @return
     * 转换成的byte数组
     */
    //第二个参数是转换长度
    public static byte[] listTobyte1(LinkedList<Byte> list, int cast_byte) {
        if (list == null || list.size() < 0)
            return null;
        byte[] bytes = new byte[cast_byte];
        int i = 0;
        Iterator<Byte> iterator = list.iterator();
        while (iterator.hasNext() && i<cast_byte) {
            bytes[i] = iterator.next();
            i++;
        }
        return bytes;
    }

    public static Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
        Bitmap bitmap = null;
        try {
            YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            image.compressToJpeg(new Rect(0, 0, width, height), 80, stream);
            bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
    //原文链接：https://blog.csdn.net/qq1137830424/article/details/81980673

    public static NetworkInfo getConnectedType(Context context) {
        if (context == null)
            return null;

        ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
            return mNetworkInfo;
        }

        return null;
    }
}
